package org.easy4j.framework.core.orm;

import org.easy4j.framework.core.orm.handler.Handlers;
import org.easy4j.framework.core.orm.page.Pager;

import java.util.List;

/**
 *
 * select 开头的函数为 直接执行sql ， sql需要自己组装 ， 其他函数不需要只需要传入条件
 *
 * @author: liuyong
 * @since 1.0
 */
public class BaseDao<M> extends AbstractDao<M> {

    public BaseDao(){
        super();
    }

    /**
     * Insert and return an identifier that indicates if the operation is successful
     *
     * @param m
     * @return
     */
    public boolean save(M m) {
        Mapping mapping = EntityMapping.getMapping(tableName);
        String sql = SQLBuilder.generateInsertSQL(tableName,mapping);
        return insert(sql, JdbcUtils.getInsertValues(m, mapping)) > 0;
    }

    /**
     * Insert and return the automatically generated primary key
     *
     * eg. Long id = save(m , Long.class) ;
     *
     * @param m
     * @param returnType  current support int long string
     * @param <T>
     * @return
     */
    public <T> T save(M m ,Class<T> returnType){
        Mapping mapping = EntityMapping.getMapping(tableName);
        String sql = SQLBuilder.generateInsertSQL(tableName,mapping);
        return insert(sql,returnType,JdbcUtils.getInsertValues(m, mapping)) ;
    }

    /**
     * update by Id column
     * @param m
     * @return
     */
    public int update(M m ){

        Mapping mapping = EntityMapping.getMapping(tableName);
        Object[] params = JdbcUtils.getUpdateValues(m,mapping);
        String sql      = SQLBuilder.generateUpdateSql(entityClass);
        return update(sql , params);
    }

    public int update(M m , String column ,Object value ) {
        return 1 ;
    }

    /**
     * <p>
     *     update sql
     *     right use :
     *     eg: update("set name=? ,age=?" , "where id = ? " ,[params])
     *     eg: update("name=? ,age=?" , "where id = ? " ,[params])
     *     eg: update(" set  name=? ,age=?" , "where id = ? " ,[params])
     *     error use :
     *     eg: update(" set\n name=? ,age=?" , "where id = ? " ,[params])
     * </p>
     * @param sets you can append `set` or not   eg:  "name=?"  also "set name=?"
     * @param condition should append where  eg : right ====> where id=?  error ====> id = ?
     * @param params
     * @return
     */
    protected int update(String sets, String condition, Object... params) {
        String sql = SQLBuilder.generateUpdateSQL(tableName, sets, condition);
        return update(sql,params);
    }

    public int delete(String condition ,Object... params){
        String sql = SQLBuilder.generateDeleteSQL(tableName,condition );
        return update(sql ,params);
    }

    public M queryObject(String condition ,Object ... params){

        String sql = SQLBuilder.generateSelectSQL( SQLBuilder.getSelectColumns(entityClass) ,
                tableName , condition );
        return selectOne(sql ,params);
    }

    public List<M> queryList(String condition,Object... params) {
        String sql = SQLBuilder.generateSelectSQL( SQLBuilder.getSelectColumns(entityClass) ,
                tableName, condition );
        return selectList(sql,params);
    }

    public List<M> queryList(int pageNumber ,int pageSize ,String condition ,Object ... params){
        String sql = SQLBuilder.generateSelectSqlForPager( SQLBuilder.getSelectColumns(entityClass) ,
                tableName, condition , pageNumber , pageSize  );
        return selectList(sql, params);
    }

    protected Pager<M> pager(int pageNumber,int pageSize,String condition ,Object ... params){
        int total = queryCount(condition ,params);
        if(total == 0){
            return null ;
        }
        List<M> data = queryList(pageNumber , pageSize ,condition,params);
        return new Pager<M>(data ,pageNumber , pageSize , total);
    }


    /**
     * 查询单一数据 支持原始类型， String ,Date TimeStamp @selectColumn
     * @param sql
     * @param returnClass
     * @param params
     * @param <T>
     * @return
     */
    @Deprecated
    public <T> T querySingleValue(Class<T> returnClass , String sql,Object... params) {
        return query(sql, Handlers.getInstance(returnClass), params);
    }

    /**
     * 查询单一数据 支持原始类型， String ,Date TimeStamp
     * @param columnName
     * @param returnClass
     * @param params
     * @param <T>
     * @return
     */
    protected <T> T selectColumn(Class<T> returnClass ,String columnName ,String condition ,Object... params) {
        String sql = SQLBuilder.generateSelectSQL( columnName , tableName , condition );
        return query(sql,Handlers.getInstance(returnClass) ,params) ;
    }

    /**
     * 查询多少条数据
     * @param condition
     * @param params
     * @return Integer.MAX 足够
     */
    public int queryCount(String condition,Object ... params){
        String sql = SQLBuilder.generateSelectCountSQL(tableName ,condition);
        return query(sql,Handlers.getInstance(Integer.class),params);
    }


}
